#include <string.h>
#include "option.h"
#include "SIM900A.h"
#include "conv.h"
#include "gprs.h"
#include "smset.h"
#include "SMS.h"

#define     CONNECT_TYPE    "TCP"
#define     CONNECT_SERVER  "www.beeiot.com"
#define     CONNECT_PORT    2015

//大棚警记录
typedef struct alarm_record{
    char dp_no;//大棚号
    char type; //报警类型
    uint16_t value; //温湿度值
}alarm_record_t;

static void _sms_alarm_temperature (const option_t *option, int dp_no, int value);
static void _sms_alarm_humidity (const option_t *option, int dp_no, int value);

static option_t *l_option = NULL; //全局设置 
static alarm_record_t l_dp_alarm_records[20]; //保存报警记录
static int rec_count = 0; //报警记录条数

/*******************************************************************************
 * Function:      SIM900A_add_dp_alarm()
 * Description:   设置大棚报警数据
 * Calls:         
 * Called By:     
 * Input:         
 *                type  --报警类型  0-温度 
 *                                  1-湿度 
 *                                  2-传感器故障
 *                                  3-射频通信故障
 *                dp_no  --大棚序号
 *                value  --当前温/湿度值
 * Return:        void
 * Others:        None
 ******************************************************************************/
void SIM900A_add_dp_alarm(int type, int dp_no, int value)
{
    int index = rec_count;
    if (index >= 20) return;
    rec_count ++;
    l_dp_alarm_records[index].dp_no = dp_no;
    l_dp_alarm_records[index].value = value;
    l_dp_alarm_records[index].type  = type;
}  

/*******************************************************************************
 * Function:      SIM900A_run_dp_alarm()
 * Description:   执行大棚数据报警
 * Calls:         
 *                PDU_alarm_cat_temperature()
 *                PDU_alarm_cat_humidity()
 *                SIM900A_send_dp_alarm()
 * Called By:     
 * Input:         
 * Return:        void
 * Others:        None
 ******************************************************************************/
int SIM900A_run_dp_alarm(void)
{
    int i;
    int ret = -1;
    char *phone_number = NULL;
    if (SIM900A_gprs_send_tcp (0) == -1) //微信报警
    {
        gprs_init(l_option->alarm_mode);
        if((SIM900A_gprs_send_tcp(0) == -1) 
                &&(SIM900A_gprs_send_tcp(0) == -1))
        {
            phone_number = SIM900A_get_telnum ();
            SMS_connect (phone_number, strlen (phone_number));
            for (i = 0; i < rec_count; i ++)
            {
                if (i == 0) //起始字段
                {
                    SMS_printf ("温湿度报警：\n");
                }
                switch (l_dp_alarm_records[i].type)
                {
                    case 0 ://温度报警
                        _sms_alarm_temperature (l_option, 
                                l_dp_alarm_records[i].dp_no,
                                l_dp_alarm_records[i].value
                                );
                        break;
                    case 1 ://湿度报警
                        _sms_alarm_humidity (l_option, 
                                l_dp_alarm_records[i].dp_no,
                                l_dp_alarm_records[i].value
                                );
                        break;
                    case 2 : //传感器故障  53f7 5927 68da 4f20 611f 5668 6545 969c
                        SMS_printf("[大棚%02d]传感器故障", l_dp_alarm_records[i].dp_no);
                        SMS_printf("\n");
                        break;
                    case 3 : //射频通信故障 53f7 5927 68da 5c04 9891 901a 4fe1 6545 969C
                        SMS_printf("[大棚%02d]射频通信故障", l_dp_alarm_records[i].dp_no);
                        SMS_printf("\n");
                        break; 
                    default :
                        break;
                }

                if (i == rec_count - 1) //结尾字段
                {
                    SMS_printf ("请尽快处理");
                }
            }
            ret = SMS_flush ();
            rec_count = 0; //报警记录数归零
            return ret;
        } 
    }
    rec_count = 0; //报警记录数归零
    return 0;
}

/*******************************************************************************
 * Function:      SIM900A_send_power_alarm()
 * Description:   发送通断电通知
 * Calls:         
 * Called By:     
 * Input:         type  --报警类型 1 --断电通知
 *                                 2 --来电通知
 * Return:        0     --成功
 *                -1    --失败
 * Others:         
 ******************************************************************************/
int SIM900A_send_power_alarm(char type) //执行断电、来电通知报警
{
    uint8_t param = 0;
    char *msg = NULL;
    int ret = -1;

    switch (type)
    {
        case 1 :
            param = 2;
            msg = "温湿度报警系统已断电，暂停报警提醒服务，请转为人工监测状态。";
            break;
        case 2 :
            param = 1;
            msg = "接通电源，温湿度报警系统已开始工作！";
            break;
        default :
            return 0;
    }

    if (SIM900A_gprs_send_tcp(param) == -1) 
    {
        gprs_init(l_option->alarm_mode);
        if((SIM900A_gprs_send_tcp(2) == -1) 
                &&(SIM900A_gprs_send_tcp(2) == -1))
        {
            ret = SMS_cprintf(SIM900A_get_telnum(), msg);     
            return ret;
        }
    }
    return 0;
}

/*******************************************************************************
 * Function:      SIM900A_send_phone_call_alarm()
 * Description:   获取系统保存的手机号并发送报警信息
 * Calls:         tel_num_check()   --检查手机号
 * 
 * Called By:     
 * Input:         void
 * Return:         
 * Others:         
 ******************************************************************************/
void SIM900A_send_phone_call_alarm(void)
{
    sm_inner_cmd_push_fifo (CMD_CALL_PHONE, 0);
}



int SIM900A_send_tcp_dp_alarm(int rec_count)
{
    int ret = -1;
    int i;
    option_dp_t *dp = NULL;

    option_t *option = SIM900A_get_options();

    if (SIM900A_perform_formatted (5000, NULL, NULL, "AT+CIPSEND\r\n") == AT_RETURN_CON)
    {
        /*l_gprs_stat.TCP_RET = -1;*/
        gprs_tcp_set_SENDSTART();
        mdelay (500);

        SIM900A_core_uprintf ("{\"param_array\": {\"alarm\":[");

        //通过TCP给服务器发送报警数据
        for (i = 0; i < rec_count; i ++)
        {
            dp =(option_dp_t *)&(option->dp[(int)l_dp_alarm_records[i].dp_no]);
            if (i > 0) SIM900A_core_uprintf (",");
            SIM900A_core_uprintf ("{\"type\": %d, \"value\": %d, \"NO\": %d}",
                    l_dp_alarm_records[i].type,
                    l_dp_alarm_records[i].value,
                    l_dp_alarm_records[i].dp_no
                    );
        }
        /*dp->humidity_low,*/
        /*option->dp[1].device_id*/
        SIM900A_core_uprintf ("], \"all\":[");

        //输出所有大棚数据
        dp = (option_dp_t *)option->dp;
        for (i = 1; i <= option->number; i ++)
        {
            if (i > 1) SIM900A_core_uprintf (",");
            SIM900A_core_uprintf ("{\"HT\": %d, \"LT\": %d, \"T\": %d, \"HH\": %d, \"N\": %d, \"H\": %d, \"LH\": %d}",
                    dp[i].temperature_high,
                    dp[i].temperature_low,
#if(PLATFORM==LPC1114)
                    m_GreenHouse.dp[i].temperature,
#else
                    1,
#endif
                    dp[i].humidity_high,
                    i,
#if(PLATFORM==LPC1114)
                    m_GreenHouse.dp[i].humidity,
#else
                    1,
#endif
                    dp[i].humidity_low);
        }

        //输出ID
        SIM900A_core_uprintf ("], \"ID\":\"%03d%03d%03d%03d\"",
                option->dp[1].device_id >> 24 & 0xff,
                option->dp[1].device_id >> 16 & 0xff,
                option->dp[1].device_id >> 8 & 0xff,
                option->dp[1].device_id >> 0 & 0xff
                );
        SIM900A_core_uprintf ("}, \"class\": \"DP\",\"method\": \"dpalarm\"}\r\n\x1a");

    }
    //等待sendok
    if(wait_timeout(is_TCP_SENDOK, 30000, 0, NULL) == -1)
    {
        ret = -1;
    }
    else
    {
        ret = 0;
    }
    return ret;
}

// type : 0 --大棚报警
// type : 1 --来电报警
// type : 2 --断电报警
// type : 3 --余额报警
int SIM900A_gprs_send_tcp(uint8_t type)
{
    int ret = -1;
    char buffer[50] = {0};
    int readlen = 0;
    if(l_option->alarm_mode == 1)
    {
        if (gprs_net_connect(CONNECT_TYPE, CONNECT_SERVER, CONNECT_PORT) == 0)
        {
            switch (type)
            {
                case 0 :
                    ret = SIM900A_send_tcp_dp_alarm(rec_count); //发送大棚温湿度报警
                    break;
                case 1 :
                    ret = SIM900A_send_tcp_power_alarm(1); //发送通电报警
                    break;
                case 2 :
                    ret = SIM900A_send_tcp_power_alarm(0); //发送断电报警
                    break;
                case 3 :
                    ret = SIM900A_send_tcp_balance(sm_get_balance()); //发送余额报警
                    break;
                default :
                    break;
            }

            if (ret == 0)
            {
                ret = -1;
                while (1)
                {
                    memset (buffer, 0, 50);
                    readlen = gprs_net_read(15000, buffer, 50);
                    if (readlen != -1) //正常接收数据
                    { 
                        DBG_PRINTF ("读取网络数据: [%d] %s\n", readlen, buffer); 
                        if (strstr(buffer, "SERVER_PROC_OK") != NULL)
                        {
                            ret = 0;
                            /*return 0;*/
                        }
                        if (readlen == 0)
                        {
                            /*ret = 0;*/
                            break;
                            /*return -1;*/
                        }
                    }
                    else
                    {
                        DBG_PRINTF("[读取网络数据错误]\n");
                        ret = -1;
                        break;
                    }
                }
            }
            else
            {
                return -1;
            }
        }
    }
    return ret;
}


/*******************************************************************************
 * Function:      PDU_alarm_cat_temperature()
 * Description:   拼接温度报警字串
 * Calls:         PDU_alarm_HT()
 * Called By:     SIM900A_run_dp_alarm()
 * Input:         option   --全局参数结构体
 *                dp_no     --大棚序号
 *                value     --温度值
 *                src       --需要拼接到的缓冲区
 * Return:        void
 * Others:        None
 ******************************************************************************/
static void _sms_alarm_temperature (const option_t *option, int dp_no, int value)
{
    if (value > option->dp[dp_no].temperature_high)
    {
        SMS_printf("[大棚%02d]温度%.01f℃高于预设%02d℃",dp_no, value/10.0, option->dp[dp_no].temperature_high/10);
        SMS_printf("\n");
    }
    if (value < option->dp[dp_no].temperature_low)
    {
        SMS_printf("[大棚%02d]温度%.01f℃低于预设%02d℃",dp_no, value/10.0, option->dp[dp_no].temperature_high/10);
        SMS_printf("\n");
    }
}

/*******************************************************************************
 * Function:      _sms_alarm_humidity()
 * Description:   湿度报警短信
 * Calls:         PDU_alarm_HT()
 * Called By:     SIM900A_run_dp_alarm()
 * Input:         option   --全局参数结构体
 *                dp_no     --大棚序号
 *                value     --温度值
 *                src       --需要拼接到的缓冲区
 * Return:        void
 * Others:        None
 ******************************************************************************/
static void _sms_alarm_humidity (const option_t *option, int dp_no, int value)
{
    if (value > option->dp[dp_no].humidity_high)
    {
        SMS_printf("[大棚%02d]湿度%.01f％高于预设%02d％",dp_no, value/10.0, option->dp[dp_no].humidity_high/10);
        SMS_printf("\n");
    }
    if (value < option->dp[dp_no].humidity_low)
    {
        SMS_printf("[大棚%02d]湿度%.01f％低于预设%02d％",dp_no, value/10.0, option->dp[dp_no].humidity_low/10);
        SMS_printf("\n");
    }
}


//发送余额报警
//balance : 话费余额
int SIM900A_send_tcp_balance(uint8_t balance)
{
    uint32_t device_id = SIM900A_get_device_id();
    if (gprs_net_connect(CONNECT_TYPE, CONNECT_SERVER, CONNECT_PORT) == 0)
    {
        return gprs_net_send_formatted ("{\"param_array\": {\"ID\":\"%03d%03d%03d%03d\",\"value\": %d },\"class\": \"DP\",\"method\": \"balance\"}\r\n\x1a",
                device_id >> 24 & 0xff,
                device_id >> 16 & 0xff,
                device_id >> 8 & 0xff,
                device_id >> 0 & 0xff,
                balance
                );
    }
   return -1;
}


//发送来电报警
//stat : 0 --电源断电
//stat : 1 --电源上电
int SIM900A_send_tcp_power_alarm(uint8_t stat)
{
    uint32_t device_id = SIM900A_get_device_id();
    return gprs_net_send_formatted  ("{\"param_array\": {\"ID\":\"%03d%03d%03d%03d\",\"stat\": %d },\"class\": \"DP\",\"method\": \"powerStat\"}\r\n\x1a",
            device_id >> 24 & 0xff,
            device_id >> 16 & 0xff,
            device_id >> 8 & 0xff,
            device_id >> 0 & 0xff,
            stat
            );
}

void SIM900A_dpalarm_set_option(option_t *option)
{
    l_option = option;
}


//
//
//   +----------------+
//   |+--------------+|
//   ||温湿度报警逻辑||
//   |+--------------+|
//   +----------------+
//                            +----------------------------+
//               手动执行 --->|Call SIM900A_add_dp_alarm() |    l_dp_alarm_records[]数组保存了报警记录
//                            +----------------------------+    调用函数后，在l_dp_alarm_records中增加一条
//                                         |
//                                         v
//                            +----------------------------+ -------------------------------------------------------------------------------+
//               手动执行 --->|Call SIM900A_run_dp_alarm()     调用函数后，扫描l_dp_alarm_records[]数组                                     |
//   +------------------------+                                根据不同状态调用不同处理温湿度报警字符串                                     |
//   |                                     |                    的函数。                                                                    |
//   |                                     |                                                                                                |
//   |                                     | Call                                                                                           |
//   |                                     |                                                                                                |
//   |       0-温度报警                    |           1-湿度报警                        2-传感器故障                                       |
//   |        +----------------------------+------------+----------------------------------+---------------------------+                    |
//   |        |                                         |                                  |                           |                    |
//   |        |                                         |                                  |                           |                    |
//   |        |                                         |                                  |                           |                    |
//   |        v                                         v                                  v                           v                    |
//   | +----------------------------+    +--------------+------------+    +--------------------------+   +-------------+------------+       |
//   | |PDU_alarm_cat_temperature() |    |PDU_alarm_cat_humidity()   |    |直接复制字符串“传感器故障“|   |直接复制字符串“射频故障“  |       |
//   | +------------+---------------+    +---------------+-----------+    +---------------+----------+   +-------------+------------+       |
//   |              |                                    |                                |                            |                    |
//   |              +------------------+-----------------+                                |                            |                    |
//   |                                 |                                                  |                            |                    |
//   |                                 v                                                  |                            |                    |
//   |              +------------------+---------------+                                  |                            |                    |
//   |              |PDU_alarm_HT()拼接温湿度度报警字串|                                  |                            |                    |
//   |              +------------------+---------------+                                  |                            |                    |
//   |                                 |                                                  v                            |                    |
//   |                                 +-------------------------+------------------------+----------------------------+                    |
//   |                                                           |
//   +-----------------------------------------------------------|--------------------------------------------------------------------------+
//                                                               |
//                                                               v
//                                           +--------------------------------------+
//                                           |SIM900A_send_dp_alarm()发送报警数据   |
//                                           |                                      |
//                                           |       验证手机号                     |
//                                           |    option_tel_num_check()            |
//                                           |             |                        |
//                                           |             v                        |
//                                           |         发送短信                     |
//                                           |     SIM900A_send_SM()                |
//                                           |                                      |
//                                           +--------------------------------------+
//     
//     
//     
//     
//     
//     
//     
